<!DOCTYPE html>
<html>

<head>
	<meta charset="utf-8">
	<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
	<title>three.js css2d - label</title>
	<style>
		* {
			margin: 0;
			padding: 0;
		}

		.label {
			color: #FFF;
			font-family: sans-serif;
			padding: 2px;
			background: rgba(0, 0, 0, .6);
		}

		canvas {
			background-image: url(imgs/starts.jpg);
			background-size: cover;
		}
	</style>
</head>

<body>

	<script type="module">

		import * as THREE from '../libs/build/three.module.js';

		import { OrbitControls } from '../libs/jsm/controls/OrbitControls.js';
		import { CSS2DRenderer, CSS2DObject } from '../libs/jsm/renderers/CSS2DRenderer.js';

		let camera, scene, renderer, labelRenderer;

		const clock = new THREE.Clock();
		const textureLoader = new THREE.TextureLoader();

		let moon;

		let earth;

		init();
		animate();
		function init() {

			const EARTH_RADIUS = 2.5;
			const MOON_RADIUS = 0.27;

			camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 200);
			camera.position.set(10, 5, 20);

			scene = new THREE.Scene();

			// const dirLight = new THREE.DirectionalLight(0xffffff);
			const dirLight = new THREE.SpotLight(0xffffff);
			dirLight.position.set(0, 0, 10);
			dirLight.intensity = 2
			dirLight.castShadow = true;
			scene.add(dirLight);

			const aLight = new THREE.AmbientLight(0xfffff)
			aLight.intensity = 0.3
			scene.add(aLight)

			// const axesHelper = new THREE.AxesHelper(5);
			// scene.add(axesHelper);

			//

			const earthGeometry = new THREE.SphereGeometry(EARTH_RADIUS, 16, 16);
			// 一种用于具有镜面高光的光泽表面的材质。
			const earthMaterial = new THREE.MeshPhongMaterial({
				// 材质的高光颜色。默认值为0x111111（深灰色）的颜色Color。
				// specular: 0x333333,
				// .specular高亮的程度，越高的值越闪亮。默认值为 30
				shininess: 5,
				// 颜色贴图。默认为null。纹理贴图颜色由漫反射颜色.color调节。
				map: textureLoader.load('textures/planets/earth_atmos_2048.jpg'),
				// 镜面反射贴图值会影响镜面高光以及环境贴图对表面的影响程度。默认值为null。
				specularMap: textureLoader.load('textures/planets/earth_specular_2048.jpg'),
				// 用于创建法线贴图的纹理。RGB值会影响每个像素片段的曲面法线，并更改颜色照亮的方式。法线贴图不会改变曲面的实际形状，只会改变光照。
				normalMap: textureLoader.load('textures/planets/earth_normal_2048.jpg'),
				// 法线贴图对材质的影响程度
				normalScale: new THREE.Vector2(1, 1)
			});
			earth = new THREE.Mesh(earthGeometry, earthMaterial);
			earth.receiveShadow = true;
			earth.castShadow = true;
			scene.add(earth);

			const moonGeometry = new THREE.SphereGeometry(MOON_RADIUS, 16, 16);
			const moonMaterial = new THREE.MeshPhongMaterial({
				shininess: 5,
				map: textureLoader.load('textures/planets/moon_1024.jpg')
			});

			moon = new THREE.Mesh(moonGeometry, moonMaterial);
			moon.castShadow = true;
			moon.receiveShadow = true;
			scene.add(moon);

			//

			const earthDiv = document.createElement('div');
			earthDiv.className = 'label';
			earthDiv.textContent = 'Earth';
			earthDiv.style.marginTop = '-1em';
			const earthLabel = new CSS2DObject(earthDiv);
			earthLabel.position.set(0, EARTH_RADIUS, 0);
			earth.add(earthLabel);

			const moonDiv = document.createElement('div');
			moonDiv.className = 'label';
			moonDiv.textContent = 'Moon';
			moonDiv.style.marginTop = '-1em';
			const moonLabel = new CSS2DObject(moonDiv);
			moonLabel.position.set(0, MOON_RADIUS, 0);
			moon.add(moonLabel);

			//

			renderer = new THREE.WebGLRenderer({ alpha: true });
			renderer.setPixelRatio(window.devicePixelRatio);
			renderer.setSize(window.innerWidth, window.innerHeight);
			renderer.shadowMap.enabled = true;
			document.body.appendChild(renderer.domElement);

			labelRenderer = new CSS2DRenderer();
			labelRenderer.setSize(window.innerWidth, window.innerHeight);
			labelRenderer.domElement.style.position = 'absolute';
			labelRenderer.domElement.style.top = '0px';
			document.body.appendChild(labelRenderer.domElement);

			const controls = new OrbitControls(camera, labelRenderer.domElement);
			controls.minDistance = 5;
			controls.maxDistance = 100;

			//

			window.addEventListener('resize', onWindowResize);

		}

		function onWindowResize() {

			camera.aspect = window.innerWidth / window.innerHeight;

			camera.updateProjectionMatrix();

			renderer.setSize(window.innerWidth, window.innerHeight);

			labelRenderer.setSize(window.innerWidth, window.innerHeight);

		}


		function animate() {

			requestAnimationFrame(animate);

			const elapsed = clock.getElapsedTime();

			moon.position.set(Math.sin(elapsed) * 5, 0, Math.cos(elapsed) * 5);
			var axis = new THREE.Vector3(0, 1, 0)
			earth.rotateOnAxis(axis, Math.PI / 128)
			renderer.render(scene, camera);
			labelRenderer.render(scene, camera);

		}

	</script>
</body>

</html>